"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseTicketText = parseTicketText;
exports.tokensToLines = tokensToLines;
exports.formatNumberToken = formatNumberToken;
exports.serializeTokens = serializeTokens;
exports.cloneTokens = cloneTokens;
exports.cycleState = cycleState;
exports.markPriceTokens = markPriceTokens;
function nextIdGenerator() {
    let counter = 0;
    return () => `token-${counter++}`;
}
function shouldSkipNumberMatch(source, start, end, matched) {
    const before = start > 0 ? source[start - 1] : '';
    const after = end < source.length ? source[end] : '';
    const lookAhead = source.slice(end, end + 6);
    if (/^\d{1,2}[:：]\d{2}$/.test(matched)) {
        return true;
    }
    if (/^\d{1,2}\.\d{1,2}$/.test(matched) && /[~\-更更新]/.test(after + lookAhead)) {
        return true;
    }
    if (/^\d{4}$/.test(matched) && after === '年') {
        return true;
    }
    if (/^\d{1,2}$/.test(matched)) {
        if (['月', '日', '号', '点', '时'].includes(after) || ['月', '日'].includes(before)) {
            return true;
        }
        if (after === ':' || after === '：' || before === ':' || before === '：') {
            return true;
        }
        if ((before === '/' || after === '/') && /号|日/.test(lookAhead)) {
            return true;
        }
        if (before === '第' && ['场', '天'].includes(after)) {
            return true;
        }
    }
    if (before === '<' && lookAhead.includes('>') && /[月日号]/.test(source.slice(start, end + 4))) {
        return true;
    }
    return false;
}
function parseTicketText(rawText, options) {
    const getId = nextIdGenerator();
    const normalized = rawText.replace(/\r\n/g, '\n');
    const regex = options.allowDecimal ? /\d+(?:\.\d+)?/g : /\d+/g;
    const tokens = [];
    let lastIndex = 0;
    let match;
    const pushTextSegment = (segment) => {
        if (!segment) {
            return;
        }
        const parts = segment.split('\n');
        parts.forEach((part, idx) => {
            if (part) {
                tokens.push({
                    type: 'text',
                    id: getId(),
                    raw: part,
                });
            }
            if (idx < parts.length - 1) {
                tokens.push({
                    type: 'linebreak',
                    id: getId(),
                });
            }
        });
    };
    while ((match = regex.exec(normalized)) !== null) {
        const [matched] = match;
        if (match.index > lastIndex) {
            pushTextSegment(normalized.slice(lastIndex, match.index));
        }
        if (shouldSkipNumberMatch(normalized, match.index, match.index + matched.length, matched)) {
            pushTextSegment(matched);
            lastIndex = regex.lastIndex;
            continue;
        }
        const precision = matched.includes('.') ? matched.split('.')[1].length : 0;
        tokens.push({
            type: 'number',
            id: getId(),
            raw: matched,
            value: Number(matched),
            precision,
            state: 'none',
        });
        lastIndex = regex.lastIndex;
    }
    if (lastIndex < normalized.length) {
        pushTextSegment(normalized.slice(lastIndex));
    }
    // Ensure trailing newline generates empty line entry
    if (normalized.endsWith('\n')) {
        tokens.push({
            type: 'linebreak',
            id: getId(),
        });
    }
    return tokens;
}
function tokensToLines(tokens) {
    const lines = [];
    let current = [];
    tokens.forEach((token) => {
        if (token.type === 'linebreak') {
            lines.push(current);
            current = [];
            return;
        }
        current.push(token);
    });
    lines.push(current);
    return lines;
}
function formatNumberToken(token) {
    if (token.precision > 0) {
        return token.value.toFixed(token.precision);
    }
    return String(Math.round(token.value));
}
function serializeTokens(tokens) {
    return tokens
        .map((token) => {
        if (token.type === 'linebreak') {
            return '\n';
        }
        if (token.type === 'number') {
            return formatNumberToken(token);
        }
        return token.raw;
    })
        .join('');
}
function cloneTokens(tokens) {
    return tokens.map((token) => ({ ...token }));
}
function cycleState(state) {
    switch (state) {
        case 'none':
            return 'yellow';
        case 'yellow':
            return 'red';
        case 'red':
        default:
            return 'none';
    }
}
function markPriceTokens(tokens) {
    const lines = tokensToLines(tokens);
    lines.forEach((line) => {
        let seenContent = false; // 是否出现过非空文本或数字（用于判断行首数字）
        line.forEach((seg) => {
            if (seg.type === 'text') {
                if (seg.raw.trim().length > 0)
                    seenContent = true;
                return;
            }
            const num = seg;
            if (!seenContent) {
                // 行头第一个数字不选中
                num.state = 'none';
                seenContent = true;
                return;
            }
            num.state = num.value > 99 ? 'yellow' : 'none';
        });
    });
}
